package cn.com.bluemoon.daps.model.utils.factory.impl.field;

import cn.com.bluemoon.daps.common.enums.DatabaseType;
import cn.com.bluemoon.daps.common.sql.SqlScriptUtils;
import cn.com.bluemoon.daps.model.entity.DapDataModelTableField;
import cn.com.bluemoon.daps.model.utils.SqlUtils;
import cn.com.bluemoon.daps.model.utils.contrast.Constant;

import com.alibaba.druid.DbType;
import com.google.common.collect.Lists;
import com.google.inject.internal.cglib.core.$LocalVariablesSorter;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.StringUtil;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author karry
 * @Data 2021/9/7
 * @Time:9:28
 */
public class PostgreFieldScript extends AbsFieldScript {

    @Override
    public String createFieldScript(List<DapDataModelTableField> fields) {
        return createFieldPublicCode(fields, DatabaseType.PGSQL);
    }

    @Override
    public void addFieldScript(List<DapDataModelTableField> fields, String tableSchema,
                               String tableName, Map<String, String> map) {

        String schema = StringUtils.isNotBlank(tableSchema) ? tableSchema + "." : "";
        List<String> scriptList = Lists.newArrayList();
        for (DapDataModelTableField field : fields) {
            StringBuffer buffer = new StringBuffer();
            createSingFieldScript(field, null, DatabaseType.PGSQL, "", buffer);
            String script = buffer.deleteCharAt(buffer.length() - 1).append(";").toString();
            String fieldComment = SqlScriptUtils.formatComment(field.getComment());
            String format = "%s%s comment on table %s%s.%s is '%s';";
            String fieldScript = String.format(format, Constant.AT, script, schema, tableName, field.getFieldName(), fieldComment);
            scriptList.add(fieldScript);
        }
        String collect = scriptList.stream().collect(Collectors.joining(" "));
        map.put(Constant.CF, collect);
    }

    @Override
    public String modifyFieldScript(DapDataModelTableField nf, DapDataModelTableField of, String tableName, String tableSchema) {
        String schema = StringUtils.isNotBlank(tableSchema) ? tableSchema + "." : "";
        StringBuffer buffer = new StringBuffer();
        // 字段名、字段类型、长度、小数点、复合类型、是否为空、缺省值(主键、复合类型暂时不做)
        if(!StringUtils.equalsIgnoreCase(nf.getFieldName(), of.getFieldName())){
            String format = "%s%s%s rename %s column to %s;";
            String renameScript = String.format(format, Constant.AT, schema, tableName, of.getFieldName(), nf.getFieldName());
            buffer.append(renameScript);
        }
        // 注释
        if(!nf.getComment().equals(of.getComment())){
            String format = "comment on column %s%s.%s is '%s';";
            String commentScript = String.format(format, schema, tableName, nf.getFieldName(), nf.getComment());
            buffer.append(commentScript);
        }
        // 字段类型、长度、小数点
        if(!nf.equals(of, DbType.postgresql)){
            String format = "%s%s%s alter column %s %s %s;";
            String dataLength = StringUtils.isBlank(nf.getLength()) ? " " : String.format("(%s%s) ",nf.getLength(),
                                SqlUtils.isNull(nf.getDecimalLength()) ? "" : "," + nf.getDecimalLength());
            String datatypeScript = String.format(format, Constant.AT, schema, tableName, nf.getFieldName(), nf.getDataType(), dataLength);
            buffer.append(datatypeScript);
        }
        // 是否为空
        if(!Objects.equals(nf.getNotNull(), of.getNotNull())){
            String format = "%s%s%s alter column %s %s;";
            String key = String.format("%s not null", nf.getNotNull() == 1 ? "set" : "drop");
            String isNullScript = String.format(format, Constant.AT, schema, tableName, nf.getFieldName(), key);
            buffer.append(isNullScript);
        }
        // 缺省值
        if(!Objects.equals(nf.getDefaultValue(), of.getDefaultValue())){
            String format = "%s%s%s alter column %s %s;";
            String defaultValue = SqlUtils.getDefaultValue(nf.getDataType(), nf.getDefaultValue());
            String key = StringUtils.isBlank(nf.getDefaultValue()) ? "drop default" : String.format("set default %s", defaultValue);
            String defaultValueScript = String.format(format, Constant.AT, schema, tableName, nf.getFieldName(), key);
            buffer.append(defaultValueScript);
        }
        return buffer.toString();
    }

    @Override
    public void deleteFieldScript(List<DapDataModelTableField> fields,
                                  String tableSchema, String tableName,
                                  Map<String, String> map) {

        String schema = StringUtils.isNotBlank(tableSchema) ? tableSchema + "." : "";
        String script = fields.stream().map(f -> String.format("drop %s", f.getFieldName())).collect(Collectors.joining(","));
        String fieldScript = String.format("%s%s%s %s;", Constant.AT, schema, tableName, script);
        map.put(Constant.DF, fieldScript);
    }
}
